#!/usr/bin/env python3
"""
阿里云ECS WebSocket服务器部署脚本
用于将WebSocket服务部署到阿里云ECS实例上，实现24/7运行
"""

import os
import sys
import json
import time
import subprocess
from datetime import datetime

class AliyunDeployer:
    def __init__(self):
        self.config = {
            'instance_id': '',  # 需要填写你的ECS实例ID
            'region': 'cn-hangzhou',
            'server_port': 8080,
            'server_host': '0.0.0.0'
        }
        
    def load_config(self):
        """加载配置文件"""
        config_file = 'aliyun_config.json'
        if os.path.exists(config_file):
            with open(config_file, 'r', encoding='utf-8') as f:
                self.config.update(json.load(f))
                
    def save_config(self):
        """保存配置文件"""
        config_file = 'aliyun_config.json'
        with open(config_file, 'w', encoding='utf-8') as f:
            json.dump(self.config, f, indent=2, ensure_ascii=False)
            
    def create_requirements_txt(self):
        """创建依赖文件"""
        requirements = [
            'websockets==11.0.3',
            'asyncio',
            'logging',
            'json',
            'datetime'
        ]
        
        with open('requirements.txt', 'w', encoding='utf-8') as f:
            for req in requirements:
                f.write(f'{req}\n')
                
    def create_systemd_service(self):
        """创建systemd服务文件"""
        service_content = f"""[Unit]
Description=Patient Management WebSocket Server
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/root/websocket_server
ExecStart=/usr/bin/python3 /root/websocket_server/websocket_server.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
"""
        
        with open('patient-websocket.service', 'w', encoding='utf-8') as f:
            f.write(service_content)
            
    def create_deploy_script(self):
        """创建部署脚本"""
        deploy_script = f"""#!/bin/bash
# 阿里云ECS WebSocket服务器部署脚本

echo "开始部署WebSocket服务器到阿里云ECS..."

# 更新系统
apt update && apt upgrade -y

# 安装Python3和pip
apt install -y python3 python3-pip

# 创建项目目录
mkdir -p /root/websocket_server
cd /root/websocket_server

# 上传文件（需要手动上传）
# scp websocket_server.py root@your-ecs-ip:/root/websocket_server/
# scp requirements.txt root@your-ecs-ip:/root/websocket_server/

# 安装依赖
pip3 install -r requirements.txt

# 创建systemd服务
cat > /etc/systemd/system/patient-websocket.service << 'EOF'
[Unit]
Description=Patient Management WebSocket Server
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/root/websocket_server
ExecStart=/usr/bin/python3 /root/websocket_server/websocket_server.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

# 重新加载systemd
systemctl daemon-reload

# 启用服务
systemctl enable patient-websocket.service

# 启动服务
systemctl start patient-websocket.service

# 检查服务状态
systemctl status patient-websocket.service

echo "部署完成！"
echo "服务状态: systemctl status patient-websocket.service"
echo "查看日志: journalctl -u patient-websocket.service -f"
echo "重启服务: systemctl restart patient-websocket.service"
"""
        
        with open('deploy_to_aliyun.sh', 'w', encoding='utf-8') as f:
            f.write(deploy_script)
            
    def create_nginx_config(self):
        """创建Nginx反向代理配置"""
        nginx_config = f"""server {{
    listen 80;
    server_name your-domain.com;  # 替换为你的域名
    
    location /ws {{
        proxy_pass http://127.0.0.1:{self.config['server_port']};
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }}
    
    location / {{
        root /var/www/html;
        index index.html;
    }}
}}
"""
        
        with open('nginx_websocket.conf', 'w', encoding='utf-8') as f:
            f.write(nginx_config)
            
    def create_firewall_script(self):
        """创建防火墙配置脚本"""
        firewall_script = f"""#!/bin/bash
# 配置防火墙规则

# 安装ufw
apt install -y ufw

# 设置默认策略
ufw default deny incoming
ufw default allow outgoing

# 允许SSH连接
ufw allow ssh

# 允许WebSocket端口
ufw allow {self.config['server_port']}

# 允许HTTP和HTTPS
ufw allow 80
ufw allow 443

# 启用防火墙
ufw --force enable

echo "防火墙配置完成"
"""
        
        with open('setup_firewall.sh', 'w', encoding='utf-8') as f:
            f.write(firewall_script)
            
    def create_monitoring_script(self):
        """创建监控脚本"""
        monitoring_script = f"""#!/bin/bash
# WebSocket服务器监控脚本

LOG_FILE="/var/log/websocket_monitor.log"
SERVICE_NAME="patient-websocket.service"

# 检查服务状态
check_service() {{
    if ! systemctl is-active --quiet $SERVICE_NAME; then
        echo "$(date): 服务未运行，正在重启..." >> $LOG_FILE
        systemctl restart $SERVICE_NAME
        sleep 5
        
        if systemctl is-active --quiet $SERVICE_NAME; then
            echo "$(date): 服务重启成功" >> $LOG_FILE
        else
            echo "$(date): 服务重启失败" >> $LOG_FILE
        fi
    fi
}}

# 检查端口是否监听
check_port() {{
    if ! netstat -tlnp | grep ":{self.config['server_port']}"; then
        echo "$(date): 端口{self.config['server_port']}未监听，重启服务..." >> $LOG_FILE
        systemctl restart $SERVICE_NAME
    fi
}}

# 主循环
while true; do
    check_service
    check_port
    sleep 60  # 每分钟检查一次
done
"""
        
        with open('monitor_websocket.sh', 'w', encoding='utf-8') as f:
            f.write(monitoring_script)
            
    def create_client_config(self):
        """创建客户端配置更新脚本"""
        client_config = f"""// 更新Android客户端配置
// 在ServerConfig.kt中更新服务器地址

object ServerConfig {{
    // 阿里云ECS服务器地址
    const val WEBSOCKET_SERVER_URL = "ws://your-ecs-ip:{self.config['server_port']}"
    const val HTTP_SERVER_URL = "http://your-ecs-ip:8080"
    
    // 备用服务器地址（可选）
    const val BACKUP_WEBSOCKET_URL = "ws://backup-server-ip:{self.config['server_port']}"
    
    // 连接超时设置
    const val CONNECTION_TIMEOUT = 30000L
    const val RECONNECT_INTERVAL = 5000L
}}
"""
        
        with open('update_client_config.kt', 'w', encoding='utf-8') as f:
            f.write(client_config)
            
    def generate_deployment_files(self):
        """生成所有部署文件"""
        print("正在生成阿里云ECS部署文件...")
        
        self.load_config()
        self.create_requirements_txt()
        self.create_systemd_service()
        self.create_deploy_script()
        self.create_nginx_config()
        self.create_firewall_script()
        self.create_monitoring_script()
        self.create_client_config()
        
        print("部署文件生成完成！")
        print("\n部署步骤：")
        print("1. 购买阿里云ECS实例（建议2核4GB）")
        print("2. 配置安全组，开放端口：22, 80, 443, 8080")
        print("3. 连接到ECS实例")
        print("4. 上传部署文件到ECS")
        print("5. 运行部署脚本：bash deploy_to_aliyun.sh")
        print("6. 更新Android客户端配置")
        
    def show_deployment_guide(self):
        """显示部署指南"""
        guide = f"""
=== 阿里云ECS WebSocket服务器部署指南 ===

1. 购买阿里云ECS实例
   - 推荐配置：2核4GB内存
   - 操作系统：Ubuntu 20.04 LTS
   - 带宽：5Mbps以上

2. 配置安全组
   - 开放端口：22 (SSH), 80 (HTTP), 443 (HTTPS), {self.config['server_port']} (WebSocket)
   - 来源：0.0.0.0/0

3. 连接到ECS实例
   ssh root@your-ecs-ip

4. 上传文件到ECS
   scp websocket_server.py root@your-ecs-ip:/root/websocket_server/
   scp requirements.txt root@your-ecs-ip:/root/websocket_server/
   scp deploy_to_aliyun.sh root@your-ecs-ip:/root/websocket_server/

5. 运行部署脚本
   cd /root/websocket_server
   chmod +x deploy_to_aliyun.sh
   bash deploy_to_aliyun.sh

6. 配置Nginx反向代理（可选）
   apt install nginx
   cp nginx_websocket.conf /etc/nginx/sites-available/websocket
   ln -s /etc/nginx/sites-available/websocket /etc/nginx/sites-enabled/
   systemctl restart nginx

7. 设置监控脚本
   chmod +x monitor_websocket.sh
   nohup ./monitor_websocket.sh > /dev/null 2>&1 &

8. 更新Android客户端配置
   - 修改ServerConfig.kt中的服务器地址
   - 重新编译APK

服务管理命令：
- 查看状态：systemctl status patient-websocket.service
- 查看日志：journalctl -u patient-websocket.service -f
- 重启服务：systemctl restart patient-websocket.service
- 停止服务：systemctl stop patient-websocket.service

注意事项：
- 确保ECS实例有公网IP
- 配置域名解析（可选）
- 定期备份数据
- 监控服务器资源使用情况
"""
        
        with open('ALIYUN_DEPLOYMENT_GUIDE.md', 'w', encoding='utf-8') as f:
            f.write(guide)
            
        print(guide)

def main():
    deployer = AliyunDeployer()
    deployer.generate_deployment_files()
    deployer.show_deployment_guide()

if __name__ == "__main__":
    main() 